package com.scatteredServer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scatteredServer.common.Result;
import com.scatteredServer.pojo.entity.*;
import com.scatteredServer.pojo.form.add.AddIndexNotice;
import com.scatteredServer.pojo.form.add.AddPosting;
import com.scatteredServer.pojo.form.add.AddPostingNotice;
import com.scatteredServer.pojo.form.update.UpdateNotice;
import com.scatteredServer.pojo.form.update.UpdatePostingDetails;
import com.scatteredServer.pojo.form.update.UpdateRoughlyPosting;
import com.scatteredServer.pojo.query.NoticeQuery;
import com.scatteredServer.pojo.query.PostingQuery;
import com.scatteredServer.pojo.query.ReadStatusQuery;
import com.scatteredServer.pojo.vo.*;
import com.scatteredServer.service.PostingService;
import com.scatteredServer.mapper.PostingMapper;
import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author admin
* @description 针对表【posting(发文表)】的数据库操作Service实现
* @createDate 2024-04-05 15:28:11
*/
@Service
public class PostingServiceImpl extends ServiceImpl<PostingMapper, Posting>
    implements PostingService{

    @Autowired
    PostingMapper postingMapper;

    @Autowired
    private JavaMailSender mailSender;

    @Override
    public Result<BaseVo<PostingRoughlyVo>> getList(PostingQuery postingQuery) {

        Page<PostingRoughlyVo> page = new Page<>(postingQuery.getCurrentPage(), postingQuery.getPageSize());
        Page<PostingRoughlyVo> result = postingMapper.getList(page, postingQuery);
         result.getRecords().stream().filter(Objects::nonNull).forEach((roughlyVo)->{
              String  teachersRead ="[]";
              if(roughlyVo.getNotReadNum() != null){
                  teachersRead = roughlyVo.getNotReadNum();
              }
              Integer notReadNumInt = 0;
             List<ReadStatus> readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
             for (ReadStatus readStatus : readStatusList) {
                 if (readStatus.getStatus().equals(0) || readStatus.getStatus() == 0) {
                     notReadNumInt++;
                 }
             }
             String notReadNumString = notReadNumInt+"人";
             roughlyVo.setNotReadNum(notReadNumString);
         });

        BaseVo<PostingRoughlyVo> criteriaBaseVo = new BaseVo<>();
        criteriaBaseVo.setCurrentPage(postingQuery.getCurrentPage());
        criteriaBaseVo.setPageSize(postingQuery.getPageSize());
        criteriaBaseVo.setAllPages(result.getPages());
        criteriaBaseVo.setAllRecordNum(result.getTotal());
        criteriaBaseVo.setRecords(result.getRecords());

        return Result.success(criteriaBaseVo);
    }

    @Override
    public Result<PostingDetailsVo> getDetailsById(String id) {
        Posting posting = postingMapper.selectById(id);

        PostingDetailsVo postingDetailsVo = new PostingDetailsVo();
        postingDetailsVo.setId(posting.getId());
        postingDetailsVo.setTitle(posting.getTitle());
        postingDetailsVo.setContext(posting.getContext());

        String string = posting.getFileSaveList().toString();
        if(string!=null&&!string.equals("")){
            System.out.println("json正常");
        }else {
            //赋值空对象
            string="[]";
        }
        List<FileSave> fileSaves = JSONArray.parseArray(string, FileSave.class);

        postingDetailsVo.setFileSaveList(fileSaves);
        postingDetailsVo.setCreateTime(posting.getCreateTime());
        postingDetailsVo.setDescription(posting.getDescription());




        return Result.success(postingDetailsVo);
    }


    /**
     *
     * 异步编程
     *
     * */
    @Override
    public Result<String> addOne(AddPosting addPosting) {
        Posting posting = new Posting();

        // 同步代码块 开始
        BeanUtil.copyProperties(addPosting, posting);
        List<FileSave> fileSaveList = addPosting.getFileSaveList();
        String fileSaveString = JSON.toJSONString(fileSaveList);
        posting.setFileSaveList(fileSaveString);
        postingMapper.insert(posting);

        // 同步代码块 结束

        // 上述内容执行完成之后直接返回结果，下列内容使用异步进行。
        CompletableFuture.runAsync(() -> {
            Integer id = posting.getId();
            List<String> teacherIds = addPosting.getTeacherIds();
            List<ReadStatus> readStatusList = new ArrayList<>();
            for (String teacherId : teacherIds) {
                ReadStatus readStatus = new ReadStatus();
                readStatus.setTeacherId(teacherId);
                readStatus.setStatus(0);
                readStatusList.add(readStatus);
            }
            String readStatusString = JSON.toJSONString(readStatusList);
            postingMapper.updateReadStatusById(id, readStatusString);
        });
        return Result.success("发文成功"); // 立即返回结果
    }

    @Override
    public Result<List<TeacherInfoMap>> getSelector() {
        List<TeacherInfoMap> selector= postingMapper.getSelector();
        return Result.success(selector);
    }

    @Transactional
    @Override
    public Result<String> deleteByIds(List<Integer> list) {
        postingMapper.deleteBatchIds(list);
        return Result.success("删除成功");
    }

    @Override
    public Result<String> updateRoughlyById(UpdateRoughlyPosting updateRoughlyPosting) {
        Posting posting = new Posting();
        BeanUtil.copyProperties(updateRoughlyPosting,posting);
        postingMapper.updateById(posting);
        return Result.success("修改成功");
    }

    @Override
    public Result<String> updateDetailsById(UpdatePostingDetails updatePostingDetails) {
        Posting posting = new Posting();
        BeanUtil.copyProperties(updatePostingDetails,posting);
        List<FileSave> fileSaveList = updatePostingDetails.getFileSaveList();
        String string = JSON.toJSONString(fileSaveList);
        posting.setFileSaveList(string);
        postingMapper.updateById(posting);
        return Result.success("修改成功");
    }


    @Override
    public Result<BaseVo<PostingReadStatusVo>> getNoticeList(NoticeQuery noticeQuery) {
        Page<PostingReadStatusVo> page = new Page<>(noticeQuery.getCurrentPage(), noticeQuery.getPageSize());

        Page<PostingReadStatusVo> result = postingMapper.getNoticeList(page, noticeQuery);
        List<PostingReadStatusVo> records = result.getRecords();

        List<TeacherInfoMap> selector = postingMapper.getSelector();

        // 映射器转map（添加查询速率）
        Map<String, String> map = new HashMap<>();
        selector.forEach(teacherInfoMap -> {
            map.put(teacherInfoMap.getTeacherId(), teacherInfoMap.getTeacherName());
        });

        BaseVo<PostingReadStatusVo> criteriaBaseVo = new BaseVo<>();
        criteriaBaseVo.setCurrentPage(noticeQuery.getCurrentPage());
        criteriaBaseVo.setPageSize(noticeQuery.getPageSize());
        criteriaBaseVo.setAllPages(result.getPages());
        criteriaBaseVo.setAllRecordNum(result.getTotal());

        List<PostingReadStatusVo> processedRecords = new ArrayList<>();
        records.forEach(postingReadStatusVo -> {
            String list ="[]";
            if(postingReadStatusVo.getList()!=null&&!postingReadStatusVo.getList().equals("")){
                list =  postingReadStatusVo.getList().toString();
            }

            List<ReadStatusVo> readStatusList = JSONArray.parseArray(list, ReadStatusVo.class);
            List<ReadStatusVo> updatedReadStatusList = new ArrayList<>();
            readStatusList.forEach(readStatusVo -> {
                // 直接从map中使用kv 键值对进行索引赋值，效率绝对高
                readStatusVo.setTeacherName(map.get(readStatusVo.getTeacherId()));
                updatedReadStatusList.add(readStatusVo);
            });
            postingReadStatusVo.setList(updatedReadStatusList);
            processedRecords.add(postingReadStatusVo);
        });
        criteriaBaseVo.setRecords(processedRecords);

        return Result.success(criteriaBaseVo);
    }



    //修改时候加锁，避免出现并发时候，修改状态未保存的情况。
    @Override
    public synchronized Result<String> sendRead(UpdateNotice updateNotice) {

        Integer postingId = updateNotice.getPostingId();
        String teacherId = updateNotice.getTeacherId();

        Posting posting = postingMapper.selectById(postingId);
        String teachersRead = posting.getTeachersRead().toString();
        List<ReadStatus> readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
        readStatusList.forEach(readStatus -> {
            if(readStatus.getTeacherId().equals(teacherId)){
                readStatus.setStatus(1);
            }
        });
        String updateJson = JSON.toJSONString(readStatusList);
        posting.setTeachersRead(updateJson);
        postingMapper.updateById(posting);

        return Result.success("更新阅读状态成功");
    }

    @Override
    public Result<ReadStatusTeacher> getReadStatus(ReadStatusQuery readStatusQuery) {

        ReadStatusTeacher readStatusTeacher = new ReadStatusTeacher();
        Integer postingId = readStatusQuery.getPostingId();
        Posting posting = postingMapper.selectById(postingId);
        String teachersRead = "[]";
        if(posting.getTeachersRead()!=null){
            teachersRead = posting.getTeachersRead().toString();
        }
        List<ReadStatus> readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
        readStatusList.forEach(readStatus -> {
            if(readStatus.getTeacherId().equals(readStatusQuery.getTeacherId())){
                readStatusTeacher.setDescription(posting.getDescription());
                readStatusTeacher.setCreateTime(posting.getCreateTime());
                readStatusTeacher.setTeacherId(readStatusQuery.getTeacherId());
                readStatusTeacher.setPostingId(posting.getId());
                readStatusTeacher.setPostingTitle(posting.getTitle());
                readStatusTeacher.setStatus(readStatus.getStatus());

            }
        });

//        list.forEach(posting -> {
//            String teachersRead = "[]";
//            if(posting.getTeachersRead()!=null){
//                teachersRead = posting.getTeachersRead().toString();
//            }
//            List<ReadStatus> readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
//            readStatusList.forEach(readStatus -> {
//                if(readStatus.getTeacherId().equals(readStatusQuery.getTeacherId())){
//
//                    ReadStatusTeacher readStatusTeacher = new ReadStatusTeacher();
//                    readStatusTeacher.setTeacherId(readStatusQuery.getTeacherId());
//                    readStatusTeacher.setPostingId(posting.getId());
//                    readStatusTeacher.setPostingTitle(posting.getTitle());
//                    readStatusTeacher.setStatus(readStatus.getStatus());
//
//                    readStatusTeacherList.add(readStatusTeacher);
//                }
//            });
//        });

        return Result.success(readStatusTeacher);
    }

    @Override
    public Result<String> getMinTimeById(String postingId) {
        Posting posting = postingMapper.selectById(postingId);
        Integer minReadTime = posting.getMinReadTime();

        return Result.success(minReadTime+" 秒");
    }

    @Autowired
    NoticeTextServiceImpl noticeTextService;

    @Autowired
    NoticeServiceImpl noticeService;

    @Override
    public Result<String> sendIndexNotice(AddIndexNotice addIndexNotice) throws UnsupportedEncodingException, AddressException {

        NoticeText noticeText = new NoticeText();
        noticeText.setNoticeContext(addIndexNotice.getNoticeText());
        noticeTextService.save(noticeText);
        Integer noticeTextId = noticeText.getId();
        List<String> teacherIdList = addIndexNotice.getTeacherIdList();
        List<Notice> list = new ArrayList<>();
        for (String teacherId : teacherIdList) {
            Notice notice = new Notice();
            notice.setNoticeTextId(noticeTextId);
            notice.setTeacherId(teacherId);
            list.add(notice);
        }
        noticeService.saveBatch(list);
        //调用发送邮件的函数，向老师发送通知邮件
        List<String> teacherIds = addIndexNotice.getTeacherIdList();
        String teacherId = teacherIds.get(0);
        Posting unreadPost = postingMapper.selectByJson(teacherId);
        List<String> mails = postingMapper.getMailByIds(teacherIds);
        for (String mail : mails) {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setSubject("学院岗位聘任与考核管理系统发文通知");
            message.setText("尊敬的: "+mail+",您有新的发文未阅读，请尽快阅读，点击"+"http://114.55.129.172/#/teacher-profile/info?id="+unreadPost.getId()+" 跳转阅读");
            message.setTo(mail);
            message.setFrom(new InternetAddress(MimeUtility.encodeText("管理员") + "<3277512331@qq.com>").toString());
            mailSender.send(message);
        }

        return Result.success("发送成功");
    }


    @Override
    public Result<String> addTeachersForPosting(AddPostingNotice addPostingNotice) {
        Posting posting = postingMapper.selectById(addPostingNotice.getPostingId());

        if (posting == null) {
            return Result.fail("找不到该发文");
        }

        String teachersRead = posting.getTeachersRead().toString();
        List<ReadStatus> readStatusList = new ArrayList<>();

        if (teachersRead != null && !teachersRead.isEmpty()) {
            readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
        }

        List<String> teacherIds = addPostingNotice.getTeacherIds();

        for (String teacherId : teacherIds) {
            boolean exists = false;
            // 检查是否已存在相同 teacherId 的 ReadStatus 对象
            for (ReadStatus readStatus : readStatusList) {
                if (readStatus.getTeacherId().equals(teacherId)) {
                    exists = true;
                    break;
                }
            }
            // 如果不存在，则添加新的 ReadStatus 对象
            if (!exists) {
                ReadStatus readStatus = new ReadStatus();
                readStatus.setTeacherId(teacherId);
                readStatus.setStatus(0);
                readStatusList.add(readStatus);
            }
        }

        String string = JSON.toJSONString(readStatusList);
        posting.setTeachersRead(string);
        postingMapper.updateById(posting);

        return Result.success("添加成功");
    }


    @Override
    public Result<String> deleteTeachersForPosting(AddPostingNotice addPostingNotice) {
        Posting posting = postingMapper.selectById(addPostingNotice.getPostingId());

        if (posting == null) {
            return Result.fail("找不到该发文");
        }

        String teachersRead = posting.getTeachersRead().toString();
        List<ReadStatus> readStatusList = new ArrayList<>();

        if (teachersRead != null && !teachersRead.isEmpty()) {
            readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
        }

        List<String> teacherIdsToDelete = addPostingNotice.getTeacherIds();

        Iterator<ReadStatus> iterator = readStatusList.iterator();
        while (iterator.hasNext()) {
            ReadStatus readStatus = iterator.next();
            if (teacherIdsToDelete.contains(readStatus.getTeacherId())) {
                iterator.remove();
            }
        }

        String string = JSON.toJSONString(readStatusList);
        posting.setTeachersRead(string);
        postingMapper.updateById(posting);
        return Result.success("删除成功");
    }

    @Override
    public Result<BaseVo<PostingRoughlyTeacherVo>> getListByTeacherId(PostingQuery postingQuery) {
        if(!postingQuery.getTeacherId().equals("")&&postingQuery.getTeacherId()!=null){
            Page<PostingRoughlyTeacherVo> page = new Page<>(postingQuery.getCurrentPage(), postingQuery.getPageSize());
            Page<PostingRoughlyTeacherVo> result = postingMapper.getListByTeacherId(page, postingQuery);
            result.getRecords().stream().filter(Objects::nonNull).forEach((roughlyVo)->{
                String  teachersRead ="[]";

                if(roughlyVo.getNotReadStatus() != null){
                    teachersRead = roughlyVo.getNotReadStatus();
                }

                String readStatusString = "未读";
                List<ReadStatus> readStatusList = JSONArray.parseArray(teachersRead, ReadStatus.class);
                for (ReadStatus readStatus : readStatusList) {
                    if (readStatus.getTeacherId().equals(postingQuery.getTeacherId()) && (readStatus.getStatus().equals(1) || readStatus.getStatus() == 1)) {
                        readStatusString = "已读";
                        break;
                    }
                }
                roughlyVo.setNotReadStatus(readStatusString);
            });

            BaseVo<PostingRoughlyTeacherVo> criteriaBaseVo = new BaseVo<>();
            criteriaBaseVo.setCurrentPage(postingQuery.getCurrentPage());
            criteriaBaseVo.setPageSize(postingQuery.getPageSize());
            criteriaBaseVo.setAllPages(result.getPages());
            criteriaBaseVo.setAllRecordNum(result.getTotal());
            criteriaBaseVo.setRecords(result.getRecords());

            return Result.success(criteriaBaseVo);
        }else {
            return Result.fail("教师id不能为空");
        }

    }

    @Override
    public Result<PostingStatusVo> postingStatus() {
        PostingStatusVo postingStatusVo = postingMapper.postingStatus();
        return Result.success(postingStatusVo);
    }

    @Override
    public Result<JobStatusVo> jobCount() {
        JobStatusVo jobStatusVo =  postingMapper.jobCount();
        return Result.success(jobStatusVo);
    }

    @Override
    public Result<List<ServiceCountVo>> serviceCount(String year) {
        List<ServiceCountVo> serviceCountVo = postingMapper.serviceCount(year);
        return Result.success(serviceCountVo);
    }


}




